package com.penghaisoft.microwms.base.web.auth.controller;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import javax.annotation.Resource;
import javax.ws.rs.core.MediaType;

import lombok.extern.slf4j.Slf4j;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSON;
import com.penghaisoft.microwms.base.web.auth.service.IBaseDataAuthService;
import com.penghaisoft.microwms.base.web.auth.service.IBaseFactoryService;
import com.penghaisoft.microwms.base.web.auth.service.IBaseResourceService;
import com.penghaisoft.microwms.base.web.auth.service.IUserService;
import com.penghaisoft.microwms.base.web.data.service.IMdWarehouseService;
import com.penghaisoft.microwms.base.web.data.service.IMdWorkareaService;
import com.penghaisoft.microwms.common.Constant;
import com.penghaisoft.microwms.common.base.model.BaseFactory;
import com.penghaisoft.microwms.common.base.model.BaseResource;
import com.penghaisoft.microwms.common.base.model.BaseUser;
import com.penghaisoft.microwms.common.base.model.BaseUserDataAuth;
import com.penghaisoft.microwms.common.base.model.BaseUserLoginLog;
import com.penghaisoft.microwms.common.controller.BaseController;
import com.penghaisoft.microwms.common.data.model.MdModelMes;
import com.penghaisoft.microwms.common.data.model.MdWarehouse;
import com.penghaisoft.microwms.common.data.model.MdWorkarea;
import com.penghaisoft.microwms.common.dto.HandResp;
import com.penghaisoft.microwms.common.dto.LoginUserInfo;
import com.penghaisoft.microwms.common.dto.Resp;
import com.penghaisoft.microwms.common.dto.TransResult;
import com.penghaisoft.microwms.common.dto.UserFactoryDto;
import com.penghaisoft.microwms.common.dto.UserMes;
import com.penghaisoft.microwms.common.dto.WorkAreaDto;
import com.penghaisoft.microwms.common.page.Pager;
import com.penghaisoft.microwms.common.service.IMesInterfaceService;
import com.penghaisoft.microwms.common.service.MesProperties;
import com.penghaisoft.microwms.common.util.CommonUtils;
import com.penghaisoft.microwms.common.util.SessionUtil;

@RestController
@RequestMapping(value = "/auth")
@Slf4j
public class LoginController extends BaseController {

	@Autowired
	private IUserService userService;

	@Autowired
	private IBaseFactoryService baseFactoryService;

	@Autowired
	private IBaseResourceService baseResourceService;

	@Autowired
	private IMdWarehouseService warehouseService;

	@Autowired
	private IMdWorkareaService workareaService;

	@Autowired
	private IBaseDataAuthService baseDataAuthService;
	
	@Autowired
	private IMesInterfaceService mesInterfaceService;
	
	@Resource
	private MesProperties mesProperties;
	
	/**
	 * 登录
	 * @param username 用户名
	 * @param password 密码
	 * @return 处理结果
	 */
	@PostMapping(value = "mes/login")
	public TransResult mesLogin(@RequestBody BaseUser baseUser) {

		BaseUser user = new BaseUser();
		user.setLoginName(baseUser.getLoginName());
		user.setPassword(CommonUtils.md5Hash(baseUser.getPassword()));
		user = userService.checkLogin(user);

		if (user==null){
			return fail("base.auth.user.syspwd.error");
		}

		//初始session中放入的信息
//		initSessionInfo(baseUser.getLoginName());
//        登录日志
		BaseUserLoginLog loginLog = new BaseUserLoginLog();
		loginLog.setCreateBy(baseUser.getLoginName());
		loginLog.setClientType("0");
		loginLog.setLogType("0");
		loginLog.setFactoryCode(getCurrentFactoryCode());
		userService.addLoginLog(loginLog);

//		密码太简单
//		if (!checkPwd(password)) {
//			return success("pwd");
//		}

//		String regex = "^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{8,20}$";
//		if (!password.matches(regex)) {
//			return success("pwd");
//		}
//		SessionUtil.setSessionCookie(response,request);
		return success();
	}
	
	/**
	 * 登录
	 * @param username 用户名
	 * @param password 密码
	 * @return 处理结果
	 */
	@PostMapping(value = "login")
	public TransResult login(String username, String password) {

		BaseUser user = new BaseUser();
		user.setLoginName(username);
		user.setPassword(CommonUtils.md5Hash(password));
		user = userService.checkLogin(user);

		if (user==null){
			return fail("base.auth.user.syspwd.error");
		}

		//初始session中放入的信息
		initSessionInfo(username);
//        登录日志
		BaseUserLoginLog loginLog = new BaseUserLoginLog();
		loginLog.setCreateBy(username);
		loginLog.setClientType("0");
		loginLog.setLogType("0");
		loginLog.setFactoryCode(getCurrentFactoryCode());
		userService.addLoginLog(loginLog);

//		密码太简单
//		if (!checkPwd(password)) {
//			return success("pwd");
//		}

//		String regex = "^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{8,20}$";
//		if (!password.matches(regex)) {
//			return success("pwd");
//		}
		SessionUtil.setSessionCookie(response,request);
		return success();
	}

	/**
	 * @Description: 手持登陆
	 * @Param:
	 * @return:
	 * @Author: zhangx
	 * @Date: 2018/5/9 13:15
	 */
	@PostMapping(value = "hand/login")
	public HandResp handLogin(@RequestBody BaseUser param) {

		BaseUser user = new BaseUser();
		user.setLoginName(param.getLoginName());
		user.setPassword(CommonUtils.md5Hash(param.getPassword()));
		user = userService.checkLogin(user);

		HandResp result = new HandResp();
		//		1.验证账号密码
		if (user != null) {
			result.setCode(Constant.SUCCESS);

//			2 查询用户的工厂
			String userId = user.getUserId();
			List<BaseFactory> factories = baseFactoryService.queryUserFactory(userId);
			if (factories!=null&&factories.size()==1) {
//				3 查询工厂下的仓库及工作区
				BaseFactory factory = factories.get(0);
				List<WorkAreaDto> dtos = queryUserWorkAreas(user,factory);
				result.setList(dtos);
//				4 查询用户的权限
				result.setValues(queryUserPerms(user));
//					锁定--暂时不锁定用户
//					lockUser(param);

//		           	 登录日志
				BaseUserLoginLog loginLog = new BaseUserLoginLog();
				loginLog.setCreateBy(param.getLoginName());
				loginLog.setClientType("1");
				loginLog.setLogType("0");
				loginLog.setFactoryCode(factory.getFactoryCode());
				userService.addLoginLog(loginLog);
			}else {
				result.setCode(Constant.FAIL);
				int size = factories==null?0:factories.size();
				result.setMsg("当前用户工厂数据不匹配,用户工厂数="+size);
			}

		}else {
			result.setCode(Constant.FAIL);
			result.setMsg("账户或密码错误");
		}

//        登录日志
		BaseUserLoginLog loginLog = new BaseUserLoginLog();
		loginLog.setCreateBy(param.getLoginName());
//		手持
		loginLog.setClientType("1");
//		登入
		loginLog.setLogType("0");
		loginLog.setFactoryCode("");
		loginLog.setRemark(result.getMsg());
		userService.addLoginLog(loginLog);
		return result;
	}

	/**
	 * 初始session中信息
	 * @param username
	 */
	private void initSessionInfo(String username) {
		// 登录用户的基本信息放入session
		BaseUser para = new BaseUser();
		para.setLoginName(username);
		BaseUser userInfo = userService.queryOne(para);
		sessionLogin(userInfo);
		//	登录用户工厂信息
		List<UserFactoryDto> factoryDtos = baseFactoryService.queryFactoryDtoByUser(userInfo);
//		ShiroUtils.setSessionValue(ShiroUtils.SESSION_FACTORY_LIST, factoryDtos);
		SessionUtil.setSessionValue(redisTemplate,SessionUtil.SESSION_FACTORY_LIST+getSessionId(), JSON.toJSONString(factoryDtos));
		if (factoryDtos!=null && factoryDtos.size()>0) {
			String factoryCode = factoryDtos.get(0).getFactoryCode();
//			ShiroUtils.setSessionValue(ShiroUtils.SESSION_CURRENT_FACTORY, factoryCode);
			SessionUtil.setSessionValue(redisTemplate,SessionUtil.SESSION_CURRENT_FACTORY+getSessionId(), factoryCode);
			initFactoryUser(factoryCode);
		}
		//获取用户的权限，将其存入缓存-zhangx
//		initUserDataAuth(userInfo);
	}

	/**
	 * 把当前登录人的工厂内的所有用户加载到缓存中
	 * @param factoryCode
	 */
	private void initFactoryUser(String factoryCode) {
		String key = Constant.FACTORY_USER_KEY + factoryCode;
		boolean exist = redisTemplate.hasKey(key);
		log.info("--用户登录时获取当前工厂下的用户--"+key+";是否存在："+exist);
		List<BaseUser> users = userService.queryUsersUnderFactory(factoryCode);
		if (!exist) {
			if (users!=null&&users.size()>0) {
				Map<String, String> map = new HashMap<>();
				for (BaseUser baseUser : users) {
					map.put(baseUser.getLoginName(), baseUser.getUserName());
				}
				redisTemplate.opsForValue().set(key, JSON.toJSONString(map), 1, TimeUnit.DAYS);;
			}

		}

	}

	/**
	 * zhangx
	 * 注销
	 * @return
	 */
	@GetMapping(value = "logout")
	public TransResult logout() {
//        登录日志
		BaseUserLoginLog loginLog = new BaseUserLoginLog();
		loginLog.setCreateBy(getLoginName());
		loginLog.setClientType("0");
		loginLog.setLogType("1");
		loginLog.setFactoryCode(getCurrentFactoryCode());
		userService.addLoginLog(loginLog);
		sessionLogout();
		return success();
	}

	/**
	 * 获取登录人信息
	 * @return TransResult
	 */
	@GetMapping(value = "userinfo")
	public TransResult userinfo() {
		//从shiro-session中获取用户基本信息
		BaseUser user = getUserInfo();

		LoginUserInfo info = new LoginUserInfo();
		user.setUserId(null);
		user.setPassword(null);
		info.setUserInfo(user);
		info.setFactories(getUserFactories());
		return success(info);
	}

	/**
	 * 获取当前人的按钮全选
	 * @return
	 */
	@PostMapping(value = "perms")
	public TransResult queryPerms() {
		String loginName = getLoginName();
		List<BaseResource> resources = baseResourceService.findBtnByLoginName(loginName);
		List<String> perms = new ArrayList<>();
		for (BaseResource baseResource : resources) {
			perms.add(baseResource.getPermission());
		}
		Map<String,List<String>> data = new HashMap<>();
		data.put("permissions", perms);
		return success(data);
	}

	/**
	 * @Title: queryLockHandUser
	 * @Description: 查询所有锁定的当前工厂的手持用户
	 * @author zhangxu
	 * @2017年9月1日:2017年9月1日:上午11:17:57
	 * @param @return
	 * @return TransResult
	 * @version V0.1
	 * @throws
	 */
	@PostMapping(value = "query/hand/lock")
	public TransResult queryLockHandUser(@RequestParam(name = "page", defaultValue = "1") int page,
										 @RequestParam(name = "rows", defaultValue = "10") int rows,
										 BaseUser cond) {
		String factoryCode = getCurrentFactoryCode();
		TransResult result = new TransResult();
		result.setCode(Constant.SUCCESS);
		Pager<BaseUser> pager = new Pager<>();
//		手持用户登录的固定key
		Set<Object> keys = redisTemplate.opsForHash().keys(Constant.HANDKEY);
//		vals = redisTemplate.opsForHash().multiGet("handUser", keys);
		if (!keys.isEmpty()) {
			List<String> loginNameList = new ArrayList<>();
			for (Object object : keys) {
				String loginName = object.toString();
				loginNameList.add(loginName);
			}
			pager = userService.queryHandLockUserList(page, rows, factoryCode, loginNameList, cond);
		}else {
//			解决没数据一直刷新--
			pager.setRecords(new ArrayList<BaseUser>());
			pager.setTotalCount(0);
		}
		result.setData(pager);
		return result;
	}

	/**
	 * @Title: releaseHandUserLock
	 * @Description: 手持用户解锁
	 * @author zhangxu
	 * @2017年9月1日:2017年9月1日:下午2:57:21
	 * @param @param cond
	 * @param @return
	 * @return TransResult
	 * @version V0.1
	 * @throws
	 */
	@PostMapping(value = "release/hand/lock")
	public TransResult releaseHandUserLock(BaseUser cond) {
		TransResult result = new TransResult();
		redisTemplate.opsForHash().delete(Constant.HANDKEY, cond.getLoginName());
		result.setCode(Constant.SUCCESS);
		return result;
	}

	/**
	 * 更改所属工厂
	 * @return
	 */
	@GetMapping(value = "changeFactory/{factoryCode}")
	public TransResult changeFactory(@PathVariable(required=true) String factoryCode) {
		//更新session中用户当前工厂
		SessionUtil.setSessionValue(redisTemplate,SessionUtil.SESSION_CURRENT_FACTORY+getSessionId(),factoryCode);
		return success();
	}

	/**
	 * @Title: modifyPwd
	 * @Description: 更改登录密码||交接密码
	 * @author zhangxu
	 * @2017年8月9日:2017年8月9日:上午9:33:53
	 * @param @param username
	 * @param @param password
	 * @param @return
	 * @return TransResult
	 * @version V0.1
	 * @throws
	 */
	@PostMapping(value = "u/pwd/sys")
	public TransResult modifyPwd(@RequestParam("OldLoginPwd") String pwdOld, @RequestParam("NewLoginPwd") String pwdNew, @RequestParam("ConfirmLoginpwd") String pwdConfirm
//			@PathVariable String type,@RequestParam("OldHandoverPwd") String rfPwdOld, @RequestParam("NewHandoverPwd") String rfPwdNew, @RequestParam("ConfirmHandoverPwd") String rfPwdConfirm
	) {
		
		TransResult transResult = new TransResult();
		
		String url = mesProperties.getUrl() + "/imes-provider/system/authority/user/update/wms";
		
		Resp resp = new Resp();
		BaseUser baseUser = new BaseUser();
		String loginName = getLoginName();
		baseUser.setLoginName(loginName);
		baseUser.setLastPwdModifed(new Date());
		baseUser.setPassword(CommonUtils.md5Hash(pwdOld).toString());
		baseUser.setRemark(CommonUtils.md5Hash(pwdNew).toString());
		resp = userService.updateUserSysPwd(baseUser);
		if(resp.getCode() != null && resp.getCode().equals("0")){
	        return fail(resp.getMsg());
		}else{
		    //Mes修改
			UserMes userUpate = new  UserMes();
			userUpate.setAccount(getLoginName());
			userUpate.setPersonCode(getLoginName());
			userUpate.setPersonName(getUserName());
			userUpate.setMarkAble("1");//		0：无效 1：有效
			userUpate.setPassword(pwdNew);
			
//			调mes新增接口
			HandResp handResp = mesInterfaceService.publicWSResp(url, MediaType.APPLICATION_JSON_TYPE, JSON.toJSONString(userUpate));
			transResult.setCode(handResp.getCode());
			transResult.setMsg(handResp.getMsg());
	        return transResult;
		}

//		if (type.equals("sys")) {//		修改系统密码
//		}else if (type.equals("rf")) {//		修改交接密码
//			baseUser.setRfPwd(rfPwdOld);
//			baseUser.setRemark(rfPwdNew);
//			resp = userService.updateUserRfPwd(baseUser);
//		}else {//		类型异常
//			resp.setCode("0");
//			resp.setMsg("service.error");
//		}
	
	}

	/**
	 * @Title: modifyRfPwd
	 * @Description: 交接密码修改
	 * @author zhangxu
	 * @2017年8月28日:2017年8月28日:下午6:20:49
	 * @param @param rfPwdOld
	 * @param @param rfPwdNew
	 * @param @param rfPwdConfirm
	 * @param @return
	 * @return TransResult
	 * @version V0.1
	 * @throws
	 */
	@PostMapping(value = "u/pwd/rf")
	public TransResult modifyRfPwd(@RequestParam("OldHandoverPwd") String rfPwdOld, @RequestParam("NewHandoverPwd") String rfPwdNew,
								   @RequestParam("ConfirmHandoverPwd") String rfPwdConfirm) {
		Resp resp = new Resp();
		BaseUser baseUser = new BaseUser();
		String loginName = getLoginName();
		baseUser.setLoginName(loginName);
		baseUser.setLastPwdModifed(new Date());
		baseUser.setRfPwd(rfPwdOld);
		baseUser.setRemark(rfPwdNew);
		resp = userService.updateUserRfPwd(baseUser);
		return fromResp(resp);
	}
	
	
    @RequestMapping(value = "init/pwd", method = RequestMethod.POST)
    public TransResult initPwd(BaseUser user) {
    	user.setLastModifiedBy(getLoginName());
        TransResult transResult = new TransResult();
        
        String url = mesProperties.getUrl() + "/imes-provider/system/authority/user/update/wms";
        //Mes修改
		UserMes userUpate = new  UserMes();
		userUpate.setAccount(user.getLoginName());
		userUpate.setPersonCode(user.getLoginName());
		userUpate.setPersonName(user.getUserName());
		userUpate.setMarkAble("1");//		0：无效 1：有效
		//userUpate.setRemark("WMS新增");
		userUpate.setUpdateUser(getLoginName());
		userUpate.setUpdateUserName(getUserName());
		userUpate.setPassword(Constant.INIT_PWD);

//		调mes修改接口
		HandResp handResp = mesInterfaceService.publicWSResp(url, MediaType.APPLICATION_JSON_TYPE, JSON.toJSONString(userUpate));
		if(handResp.getCode() != null && handResp.getCode().equals("0")){
			transResult.setCode(handResp.getCode());
			transResult.setMsg(handResp.getMsg());
	        return transResult;
		}else{
			user.setPassword(CommonUtils.md5Hash(Constant.INIT_PWD).toString());
			int resp = userService.initPwd(user);
			if(resp > 0){
				transResult.setCode(Constant.SUCCESS);
		        transResult.setMsg("重置成功");
			}else{
				transResult.setCode(Constant.FAIL);
		        transResult.setMsg("重置失败");
			}
	        return transResult;
		}
    }

	/**
	 * 查询用户的工作区
	 * @param user
	 * @param factory
	 * @return
	 */
	private List<WorkAreaDto> queryUserWorkAreas(BaseUser user,BaseFactory factory){
		List<WorkAreaDto> dtos = new ArrayList<>();
		MdWarehouse condition = new MdWarehouse();
		condition.setFactoryCode(factory.getFactoryCode());
//		工厂下的仓库
		List<MdWarehouse> warehouses = warehouseService.queryWarehousesUnderFactory(condition);
		if (warehouses!=null&&warehouses.size()>0) {
			for (MdWarehouse mdWarehouse : warehouses) {
//				有权限的工作区
				List<WorkAreaDto> tmpAreas = assemWorkAreasByWhAndAuth(mdWarehouse,user);
				for (WorkAreaDto workAreaDto : tmpAreas) {
					workAreaDto.setWarehouseCode(mdWarehouse.getWarehouseCode());
					workAreaDto.setWarehouseName(mdWarehouse.getWarehouseName());
					workAreaDto.setWarehouseType(mdWarehouse.getWarehouseType());
					dtos.add(workAreaDto);
				}
			}
		}
		return dtos;
	}

	/**
	 * 查询用户有权限的工作区
	 * @param mdWarehouse
	 * @param user
	 * @return
	 */
	private List<WorkAreaDto> assemWorkAreasByWhAndAuth(MdWarehouse mdWarehouse,BaseUser user){
		List<WorkAreaDto> areas = new ArrayList<>();
//		1-1 根据仓库获取工作区
		MdWorkarea cond1 = new MdWorkarea();
		cond1.setActiveFlag("1");
		cond1.setWhCode(mdWarehouse.getWarehouseCode());
		List<MdWorkarea> whWorkareas = workareaService.queryWorkAreasUnderWh(cond1);

//		1-2 当前数据权限的工作区
		List<BaseUserDataAuth> authWorkareas = baseDataAuthService.queryUserDataAuth(user);
		for (MdWorkarea whWorkarea : whWorkareas) {
			for (BaseUserDataAuth authWorkarea : authWorkareas) {
				if (authWorkarea.getNormalUserBuzType().equals("workarea")&&whWorkarea.getWorkareaCode().equals(authWorkarea.getBuzCode())) {
					WorkAreaDto dto = new WorkAreaDto();
					dto.setWorkareaCode(whWorkarea.getWorkareaCode());
					dto.setWorkareaName(whWorkarea.getWorkareaName());
					areas.add(dto);
				}else {
					continue;
				}
			}
		}

		return areas;
	}

	/**
	 * 查询用户的菜单
	 * @param user
	 * @return
	 */
	private List<String> queryUserPerms(BaseUser user){
		List<BaseResource> perms = baseResourceService.findHandPermissionsByUser(user.getUserId());
		List<String> handPermsList = new ArrayList<>();
		for (BaseResource baseResource : perms) {
			handPermsList.add(baseResource.getHref());
		}
		return handPermsList;
	}

	/**
	 * @Title: initUserDataAuth
	 * @Description: 将用户的数据权限放入缓存
	 * @author zhangxu
	 * @2017年3月31日:2017年3月31日:上午10:45:10
	 * @param @param userInfo
	 * @return void
	 * @throws
	 */
//	private void initUserDataAuth(BaseUser userInfo) {
//		log.info("登录时加载用户数据权限 redis dataAuth:"+userInfo.getLoginName());
//		List<BaseUserDataAuth> userDataAuths = baseDataAuthService.queryUserDataAuth(userInfo);
//		redisTemplate.opsForValue().set(Constant.DATA_AUTH_PREFIX+userInfo.getLoginName(), JSON.toJSONString(userDataAuths));
//	}


	@PostMapping(value = "test")
	public TransResult test(String username, String password) {
		return new TransResult("1","hahaha");
	}


}
